package com.mazaiting.one;

import java.net.HttpURLConnection;

import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import com.mazaiting.util.JadyerUtil;

/**
 * 服务端消息处理器
 * 下面是服务端消息处理器，它主要用来处理业务分发
 * 目前只接收两种请求：TCP请求的固定业务编码为10005，
 * HTTP请求的固定业务编码为/login（http://127.0.0.1:8000/login）
 * @author mazaiting
 */
public class ServerHandler extends IoHandlerAdapter {
    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        System.out.println("请求进入闲置状态...回路即将关闭...");
        session.closeOnFlush();
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        System.out.println("请求处理遇到异常...回路即将关闭...");
        cause.printStackTrace();
        session.closeOnFlush();
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    	System.out.println("已回应给Client");
        if(null != session){
            session.closeNow();
        }
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        String respData;
        Token token = (Token)message;
        //打印收到的原始报文
//        System.out.println("渠道:" + token.getBusiType() + "  交易码:" + token.getBusiCode() + "  完整报文(HEX):"+JadyerUtil.buildHexStringWithASCII(JadyerUtil.getBytes(token.getFullMessage(), "UTF-8")));
        StringBuilder sb = new StringBuilder();
        sb.append("\r\n------------------------------------------------------------------------------------------");
        sb.append("\r\n【通信双方】").append(session);
        sb.append("\r\n【收发标识】Receive");
        sb.append("\r\n【报文内容】").append(token.getFullMessage());
        sb.append("\r\n------------------------------------------------------------------------------------------");
        System.out.println(sb.toString());
        //根据请求的业务编码做不同的处理
        switch (token.getBusiCode()) {
            case "/":
                respData = this.buildHTTPResponseMessage("<h2>欢迎访问由Mina2.0.16编写的Web服务器</h2>");
                break;
            case "/favicon.ico":
                //<link rel="icon" href="http://jadyer.cn/favicon.ico" type="image/x-icon"/>
                //<link rel="shortcut icon" href="http://jadyer.cn/favicon.ico" type="image/x-icon"/>
                String httpResponseMessageBody = "<link rel=\"icon\" href=\"http://jadyer.cn/favicon.ico\"";
                httpResponseMessageBody += " type=\"image/x-icon\"/>\n";
                httpResponseMessageBody += "<link rel=\"shortcut icon\" href=\"http://jadyer.cn/favicon.ico\"";
                httpResponseMessageBody += " type=\"image/x-icon\"/>";
                respData = this.buildHTTPResponseMessage(httpResponseMessageBody);
                break;
            case "/login":
                System.out.println("收到请求参数=[" + token.getBusiMessage() + "]");
                respData = this.buildHTTPResponseMessage("登录成功");
                break;
            case "10005":
                System.out.println("收到请求参数=[" + token.getBusiMessage() + "]");
                respData = "00003099999999`20130707144028`";
                break;
            default:
                switch (token.getBusiType()) {
                    case Token.BUSI_TYPE_TCP:
                        respData = "ILLEGAL_REQUEST";
                        break;
                    case Token.BUSI_TYPE_HTTP:
                        respData = this.buildHTTPResponseMessage(501, null);
                        break;
                    default:
                        respData = "UNKNOWN_REQUEST";
                        break;
                }
                break;
        }
        //打印应答报文
        sb.setLength(0);
        sb.append("\r\n------------------------------------------------------------------------------------------");
        sb.append("\r\n【通信双方】").append(session);
        sb.append("\r\n【收发标识】Response");
        sb.append("\r\n【报文内容】").append(respData);
        sb.append("\r\n------------------------------------------------------------------------------------------");
        System.out.println(sb.toString());
        session.write(respData);
    }

    /**
     * 构建HTTP响应报文
     * 该方法默认构建的是HTTP响应码为200的响应报文
     * @param httpResponseMessageBody HTTP响应报文体
     * @return 包含了HTTP响应报文头和报文体的完整报文
     */
    private String buildHTTPResponseMessage(String httpResponseMessageBody){
        return this.buildHTTPResponseMessage(HttpURLConnection.HTTP_OK, httpResponseMessageBody);
    }

    /**
     * 构建HTTP响应报文
     * 200--请求已成功，请求所希望的响应头或数据体将随此响应返回...即服务器已成功处理了请求
     * 400--由于包含语法错误，当前请求无法被服务器理解...除非进行修改，否则客户端不应该重复提交这个请求，即错误请求
     * 500--服务器遇到一个未曾预料的状况，致其无法完成请求的处理...一般该问题都会在服务器的程序码出错时出现，即服务器内部错误
     * 501--服务器不支持当前请求所需的某功能...当服务器无法识别请求，且无法支持其对任何资源的请求时，可能返回此代码，即尚未实施
     * @param httpResponseCode        HTTP响应码
     * @param httpResponseMessageBody HTTP响应报文体
     * @return 包含了HTTP响应报文头和报文体的完整报文
     */
    private String buildHTTPResponseMessage(int httpResponseCode, String httpResponseMessageBody){
        if(httpResponseCode == HttpURLConnection.HTTP_OK){
            StringBuilder sb = new StringBuilder();
            sb.append("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: ");
            sb.append(JadyerUtil.getBytes(httpResponseMessageBody, "UTF-8").length);
            sb.append("\r\n\r\n");
            sb.append(httpResponseMessageBody);
            return sb.toString();
        }
        if(httpResponseCode == HttpURLConnection.HTTP_BAD_REQUEST){
            return "HTTP/1.1 400 Bad Request";
        }
        if(httpResponseCode == HttpURLConnection.HTTP_INTERNAL_ERROR){
            return "HTTP/1.1 500 Internal Server Error";
        }
        return "HTTP/1.1 501 Not Implemented";
    }
}
